from datastore.resource import *
from datastore.uri import *
from runtime.nodelogger import NodeLogger
from runtime.service import *
import adaptor
import logging

class DocumentService(Service):
    
    DOC_NOT_FOUND_MSG = 'Document %s not found.'
    
    def cb_start(self, uri, action, res):       
        self.spaces.set_process(Uri('internal:adaptor/document/'),self.cb_get_document)

    def cb_get_document(self, uri, action, res):
        if uri.split()[-1] == 'response':
            # we are not doing anything with the response so we can safely ignore it. 
            return
        if action == Spaces.ACTION_EXISTS:
            return False
        elif action == Spaces.ACTION_PUT:
            self.logger.log(logging.DEBUG, "Requesting SPEAR Document")
              
            query_data = res.query_data
            spear_ref_no = query_data['spearRef']
            doc_id = query_data['docID']
            
            # check the application exists
            app_resource = self.spaces.get(Uri("spear:app/%s" % spear_ref_no))
            if app_resource is None:
                response = Resource(type='term:eplanning/adaptor/error')
                response.h1_header = adaptor.ERROR_H1_HEADER
                response.error = adaptor.APP_NOT_FOUND_MSG % spear_ref_no
            # application exists now check if document exists
            else:
                document_type = self._get_document_type(doc_id, app_resource)
                if document_type != None and self.is_data_ready(doc_id, document_type, app_resource):
                    if document_type == adaptor.DOC_TYPE_RESPONSIBLE_AUTHORITY_REF_NUM :
                        response = Resource(type='term:eplanning/adaptor/document-council-ref-num/data')
                        response.h1_header = document_type
                        response.spear_reference_number = spear_ref_no
                        response.council_reference_number_1 = app_resource.sid072a_dict['sid072a_reference_number_1']
                        if 'sid072a_reference_number_2' in app_resource.sid072a_dict:
                            response.council_reference_number_2 = app_resource.sid072a_dict['sid072a_reference_number_2']
                        else:
                            response.council_reference_number_2 = None
                    elif document_type == 'Referral Request' :
                        response = Resource(type='term:eplanning/adaptor/document-referral-request/data')
                        response.h1_header = document_type
                        response.spear_reference_number = spear_ref_no                    
                        response.referrals = {}
                        sid061a_dict = app_resource.sid061a_dict_dict[doc_id]
                        for ra_name, sid061a_ra_dict in sid061a_dict['sid061a_ra_dict_dict'].items():
                            referral = {}
                            referral['referral_requirements'] = sid061a_ra_dict['sid061a_ra_requirements']
                            referral['council_ra_comments'] = sid061a_ra_dict['sid061a_council_ra_comments']
                            response.referrals[ra_name] = referral
                    elif document_type == adaptor.DOC_TYPE_ACCEPT_REJECT :
                        document_dict = app_resource.sid005a_dict_dict[doc_id]    
                        response = Resource(type='term:eplanning/adaptor/document-accept-reject/data')
                        response.h1_header = document_type
                        response.version_number = document_dict['sid005a_current_document_version_number']
                        response.outcome = document_dict['sid005a_current_document_outcomesuffixcommand_suffix']
                        response.submitted_date = document_dict['sid005a_current_document_submitted_date']
                        response.authenticated_by = document_dict['sid005a_current_document_authenticated_by']
                        response.spear_reference_number = spear_ref_no
                        response.doc_id = doc_id
                        response.has_attachment = False
                        if 'sid005a_current_document_size' in document_dict and document_dict['sid005a_current_document_size']:
                            # check if the attachment has been downloaded yet
                            if self.spaces.exists(Uri('spear:app-attachment/%s' % doc_id)):
                                response.has_attachment = True
                            else:
                                response.has_attachment = False
                else:
                    # the document type return doesn't match any of the cases above or the data 
                    # for that document hasn't been downloaded yet
                    # NOTE: the document_type could be None as the documents for this app
                    # haven't been added to the resource yet. Either way, we'll return an 
                    # error saying we can't find the document requested
                    response = Resource(type='term:eplanning/adaptor/error')
                    response.h1_header = adaptor.ERROR_H1_HEADER
                    response.error = DocumentService.DOC_NOT_FOUND_MSG % doc_id                    
            # Our response will go to the request uri + 'response'
            response_uri = uri + 'response'
                                    
            self.spaces.put(response_uri, response)
            return response_uri
        else:
            return None
    
    def is_data_ready(self, doc_id, document_type, app_resource):
        if document_type == adaptor.DOC_TYPE_RESPONSIBLE_AUTHORITY_REF_NUM:
            return app_resource.has_var('sid072a_dict')
        elif document_type == 'Referral Request':
            return app_resource.has_var('sid061a_dict_dict') and doc_id in app_resource.sid061a_dict_dict
        elif document_type == adaptor.DOC_TYPE_ACCEPT_REJECT:
            return app_resource.has_var('sid005a_dict_dict') and doc_id in app_resource.sid005a_dict_dict
        else:
            return False
        
    def _get_document_type(self, doc_id, app_res):
        try:
            for doc in app_res.sid004_dict['sid004_attachment_dict_list']:
                if doc['sid004_doc_id'] == doc_id:
                    return doc['sid004_doctype']
        except:
            # if an exception occurs whether it's because the sid004_dict or 
            # sid004_attachment_dict_list doesn't exist, we will return 
            # None to say the document type is not found
            return None